package org.ielse.frame.view;

import org.ielse.frame.App;
import org.ielse.frame.util.BaseUtil;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;

public class ShinyLayout extends FrameLayout {

	private ShinyView viewShiny1, viewShiny2;

	private ShinyView s1, s2;

	public ShinyLayout(Context context) {
		super(context);
		viewShiny1 = new ShinyView(context);
		viewShiny1.setVisibility(View.GONE);
		addView(viewShiny1);
		viewShiny2 = new ShinyView(context);
		viewShiny2.setVisibility(View.GONE);
		addView(viewShiny2);
	}

	public interface DispatchTouchEventListener {
		void onDispatchTouchEvent(MotionEvent ev);
	}

	private DispatchTouchEventListener dispatchTouchEventListener;

	public void setDispatchTouchEventListener(DispatchTouchEventListener dispatchTouchEventListener) {
		this.dispatchTouchEventListener = dispatchTouchEventListener;
	}

	@Override public boolean dispatchTouchEvent(MotionEvent ev) {
		if (dispatchTouchEventListener != null) {
			dispatchTouchEventListener.onDispatchTouchEvent(ev);
		}

		boolean showShinyTrace = App.i().getAppSettings().isShinyTrace();
		if (showShinyTrace) {
			switch (ev.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:
				s1 = viewShiny1;
				s2 = viewShiny2;

				s1.setTranslationX(ev.getX(0) - viewShiny1.halfWidth);
				s1.setTranslationY(ev.getY(0) - viewShiny1.halfWidth);
				break;
			case MotionEvent.ACTION_MOVE:
				if (View.VISIBLE != s1.getVisibility()) {
					s1.setVisibility(View.VISIBLE);
				}
				s1.setTranslationX(ev.getX(0) - viewShiny1.halfWidth);
				s1.setTranslationY(ev.getY(0) - viewShiny1.halfWidth);

				if (ev.getPointerCount() > 1) {
					if (View.VISIBLE != s2.getVisibility()) {
						s2.setVisibility(View.VISIBLE);
					}
					s2.setTranslationX(ev.getX(1) - viewShiny2.halfWidth);
					s2.setTranslationY(ev.getY(1) - viewShiny2.halfWidth);
				}
				break;
			case MotionEvent.ACTION_POINTER_DOWN:
				if (ev.getActionIndex() == 0) {
					s1 = viewShiny1;
				}
				break;
			case MotionEvent.ACTION_POINTER_UP:
				if (ev.getPointerCount() == 2) {
					if (ev.getActionIndex() == 0) {
						s1.animator.start();
						s1 = viewShiny2;
					}
					else {
						if (View.VISIBLE != s2.getVisibility()) {
							s2.setVisibility(View.VISIBLE);
						}
						s2.animator.start();
					}
				}
				break;
			case MotionEvent.ACTION_CANCEL:
			case MotionEvent.ACTION_UP:
				if (View.VISIBLE != s1.getVisibility()) {
					s1.setVisibility(View.VISIBLE);
				}
				s1.animator.start();
				break;
			}
		}
		return super.dispatchTouchEvent(ev);
	}

	@Override public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			return true;
		}
		return super.onTouchEvent(event);
	}

	public static class ShinyView extends View {
		private final Paint paint = new Paint();
		private int shinyWidth, halfWidth;
		private ValueAnimator animator;

		public ShinyView(Context context) {
			super(context);
			setLayerType(LAYER_TYPE_SOFTWARE, null);
			paint.setAntiAlias(true);

			WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
			DisplayMetrics outMetrics = new DisplayMetrics();
			wm.getDefaultDisplay().getMetrics(outMetrics);

			shinyWidth = BaseUtil.isScreenVertical((Activity) context) ? (int) (outMetrics.widthPixels * 0.1f)
					: (int) (outMetrics.heightPixels * 0.1f);
			halfWidth = shinyWidth / 2;

			animator = ValueAnimator.ofFloat(1, 1.5f).setDuration(400);
			animator.setInterpolator(new DecelerateInterpolator(2));
			animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
				@Override public void onAnimationUpdate(ValueAnimator animation) {
					float scale = (Float) animation.getAnimatedValue();
					float f = animation.getAnimatedFraction();
					setScaleX(scale);
					setScaleY(scale);
					setAlpha(1 - f);
				}
			});
			animator.addListener(new AnimatorListenerAdapter() {
				@Override public void onAnimationEnd(Animator animation) {
					setVisibility(View.GONE);
					setAlpha(1);
					setScaleX(1);
					setScaleY(1);
				}
			});
		}

		@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
			setMeasuredDimension(shinyWidth, shinyWidth);
		}

		@Override protected void onDraw(Canvas canvas) {
			paint.setColor(0xffffffff);
			paint.setStyle(Style.FILL);
			canvas.drawCircle(shinyWidth / 2, shinyWidth / 2, shinyWidth / 2, paint);
		}
	}
}
